package net.luohuasheng.bee.proxy.mybatis.common.enums;

import net.luohuasheng.bee.proxy.mybatis.executor.processor.*;
import org.apache.ibatis.mapping.SqlCommandType;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author luohuasheng
 */
public class BasicMethod {

    private static final Map<String, BasicMethod> METHODS = new HashMap<>();

    public static final BasicMethod METHOD_INSERT = new BasicMethod("insert", SqlCommandType.INSERT, InsertProcessor.class);

    public static final BasicMethod METHOD_INSERT_BATCH = new BasicMethod("insertBatch", SqlCommandType.INSERT, InsertBatchProcessor.class);

    public static final BasicMethod METHOD_INSERT_SELECTIVE = new BasicMethod("insertSelective", SqlCommandType.INSERT, InsertSelectiveProcessor.class);

    public static final BasicMethod METHOD_UPDATE_ENTITY_BY_ID = new BasicMethod("updateEntityById", SqlCommandType.UPDATE, UpdateEntityByIdProcessor.class);

    public static final BasicMethod METHOD_SAVE_OR_UPDATE_BY_ID = new BasicMethod("saveOrUpdateById", SqlCommandType.INSERT, SaveOrUpdateByIdProcessor.class);

    public static final BasicMethod METHOD_SAVE_OR_UPDATE_BY_UNIQUES = new BasicMethod("saveOrUpdateByUniques", SqlCommandType.INSERT, SaveOrUpdateByUniquesProcessor.class);

    public static final BasicMethod METHOD_UPDATE_BY_ID = new BasicMethod("updateById", SqlCommandType.UPDATE, UpdateByIdProcessor.class);

    public static final BasicMethod METHOD_UPDATE_ENTITY = new BasicMethod("updateEntity", SqlCommandType.UPDATE, UpdateEntityProcessor.class);

    public static final BasicMethod METHOD_GET_BY_ID = new BasicMethod("getById", SqlCommandType.SELECT, GetByIdProcessor.class);

    public static final BasicMethod METHOD_GET_LIST = new BasicMethod("getEntityList", SqlCommandType.SELECT, GetEntityProcessor.class);

    public static final BasicMethod METHOD_GET_COUNT = new BasicMethod("getEntityCount", SqlCommandType.SELECT, GetEntityCountProcessor.class);

    public static final BasicMethod METHOD_GET = new BasicMethod("getEntity", SqlCommandType.SELECT, GetEntityProcessor.class);

    public static final BasicMethod METHOD_GET_LIST_FOR_PAGE = new BasicMethod("getEntityListForPage", SqlCommandType.SELECT, GetEntityProcessor.class);

    public static final BasicMethod METHOD_DELETE_ENTITY = new BasicMethod("deleteEntity", SqlCommandType.DELETE, DeleteEntityProcessor.class);

    public static final BasicMethod METHOD_DELETE_BY_ID = new BasicMethod("deleteById", SqlCommandType.DELETE, DeleteByIdProcessor.class);

    public static final BasicMethod METHOD_GET_VALUE = new BasicMethod("getValue", SqlCommandType.SELECT, GetValueProcessor.class);

    public static final BasicMethod METHOD_GET_VALUES = new BasicMethod("getValues", SqlCommandType.SELECT, GetValueProcessor.class);

    public static final BasicMethod METHOD_GET_VALUES_FOR_PAGE = new BasicMethod("getValuesForPage", SqlCommandType.SELECT, GetValueProcessor.class);


    private final String code;
    private final SqlCommandType sqlCommandType;
    private final Class<? extends BaseProcessor> processorClass;

    public static Collection<BasicMethod> values() {
        return METHODS.values();
    }

    public static BasicMethod getMethodByCode(String code) {
        for (BasicMethod driverType : BasicMethod.values()) {
            if (driverType.code.equals(code)) {
                return driverType;
            }
        }
        return null;
    }

    static {
        for (Field field : BasicMethod.class.getFields()) {
            if (field.getType().equals(BasicMethod.class)) {
                try {
                    BasicMethod driverType = (BasicMethod) field.get(BasicMethod.class);
                    METHODS.put(driverType.code, driverType);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public BasicMethod(String code, SqlCommandType sqlCommandType, Class<? extends BaseProcessor> processorClass) {
        this.code = code;
        this.sqlCommandType = sqlCommandType;
        this.processorClass = processorClass;
    }

    public String getCode() {
        return code;
    }

    public SqlCommandType getSqlCommandType() {
        return sqlCommandType;
    }

    public Class<? extends BaseProcessor> getProcessorClass() {
        return processorClass;
    }
}
